package Core;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class Connection 
{
	private static SocketChannel sChannel=null;
	private static ConnectionListener listener=null;
	private static Thread listenerThread=null;
	private static ByteBuffer outbuf=null;
	
	
	/**
	 * A GUI class can request to disconnect entirely from the server.
	 * That class is responsible to switch GUI's and avoid using the closed connection.
	 */
	public static void disconnect()
	{
		if(sChannel == null) return;
		
		listenerThread.interrupt();
		
		try 
		{
			sChannel.close();
			sChannel = null;
		} 
		catch (IOException e) 
		{
			sChannel = null;
		}
		
	}
	
	/**
	 * Establish connection with server.
	 * Also creates the listening service.
	 * @param host Server IP OR DNS name
	 * @param port Server port
	 * @return true upon total success, false otherwise.
	 */
	public static boolean connect(String host, int port)
	{
		if(sChannel != null)
		{
			try 
			{
				sChannel.close();
				sChannel = null;
			} 
			catch (IOException e) 
			{
				sChannel = null;
			}
		}
		try 
		{
			sChannel=SocketChannel.open();
		} 
		catch (IOException e) 
		{
			return false;
		}
		try 
		{
			sChannel.connect(new InetSocketAddress(host, port));
			sChannel.configureBlocking(true); 
			listener = new ConnectionListener(sChannel);
			listenerThread = new Thread(listener);
			listenerThread.start();
			return true;
		} 
		catch(IOException e)
		{
			try 
			{
				sChannel.close();
				sChannel = null;
			} catch (IOException e1) {sChannel = null;}
            return false;
		}
	}
	
	public static boolean isConnected()
	{
		return sChannel != null;
	}
	
	public static void send(String msg)
	{
		msg += ConnectionListener.MESSAGE_DELIMITER;
		try 
		{
			outbuf = ByteBuffer.wrap(msg.getBytes("UTF-8"));
		} 
		catch (UnsupportedEncodingException e1) 
		{
			return;
		}
		while (outbuf.remaining() > 0) 
		{
			try 
			{
				sChannel.write(outbuf);
			} catch (IOException e) 
			{
				return;
			}
		}
	}
	
}
